﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Assist;
using Autodesk.Revit.DB;
using YJKSparseBreadth.Properties;
using YJKGeometryFuncs;

namespace YJKSparseBreadth.ModelLayer
{
	public class BuildingRuleBean
	{
		public static double GroundElevation
		{
			get
			{
				return BuildingRuleBean.m_GroundElevation;
			}
			private set
			{
				BuildingRuleBean.m_GroundElevation = value;
			}
		}

		internal FireLevelEnum UseFireLevel
		{
			get
			{
				return this.m_useFireLevel;
			}
			private set
			{
				this.m_useFireLevel = value;
			}
		}

		internal RuleKindEnum UseRuleKindEnum
		{
			get
			{
				return this.m_useRuleKindEnum;
			}
			private set
			{
				this.m_useRuleKindEnum = value;
			}
		}

		public BuildingRuleBean(int RuleTypeIndex, string sMinEvacuationDescrib)
		{
			this.m_useRuleKindEnum = (RuleKindEnum)RuleTypeIndex;
			string[] array = sMinEvacuationDescrib.Split(new char[]
			{
				','
			});
			this.m_lstAllMinEvacuationWidth = new List<double>();
			foreach (string s in array)
			{
				this.m_lstAllMinEvacuationWidth.Add(double.Parse(s));
			}
		}

		public static void SetAllLevel(List<Level> lstAllLevels)
		{
			BuildingRuleBean.m_lstAllLevels = new List<Level>();
			BuildingRuleBean.m_lstAllLevels.AddRange(lstAllLevels);
			BuildingRuleBean.MakeLevelLimit();
		}

		internal LevelKindEnum CalculateLevelKind(AreaPacker_EvacuationWidth inputArea)
		{
			double useLevelZ = inputArea.UseLevelZ;
			int num = 0;
			while (num < BuildingRuleBean.m_lstLevelKindEnum.Count - 1 && (Geometry.LessThan(useLevelZ, BuildingRuleBean.m_lstLevelKindEnum[num]) || !Geometry.LessThan(useLevelZ, BuildingRuleBean.m_lstLevelKindEnum[num + 1])))
			{
				num++;
			}
			if (num <= Enum.GetValues(typeof(LevelKindEnum)).Length - 1 && !Geometry.IsEqual(useLevelZ, BuildingRuleBean.m_lstLevelKindEnum[num], BuildingRuleBean.tolerance) && BuildingRuleBean.IfLevelIsMidLevel(inputArea.m_ThisLevel) && Geometry.LessThan(useLevelZ, Utility.ValueZero))
			{
				num++;
			}
			if (num > Enum.GetValues(typeof(LevelKindEnum)).Length - 1)
			{
				num = Enum.GetValues(typeof(LevelKindEnum)).Length - 1;
			}
			return (LevelKindEnum)num;
		}

		internal double CalculateMinEvacuationWidth(LevelKindEnum inputLevelKind)
		{
			return this.m_lstAllMinEvacuationWidth[(int)inputLevelKind];
		}

		private static void MakeLevelLimit()
		{
			BuildingRuleBean.m_lstLevelKindEnum = new List<double>();
			BuildingRuleBean.m_lstLevelKindEnum.Add(double.MinValue);
			double item = AssistFunc.mmToFeet(-10000.0);
			BuildingRuleBean.m_lstLevelKindEnum.Add(item);
			BuildingRuleBean.m_lstLevelKindEnum.Add(BuildingRuleBean.GroundElevation);
			List<Level> list = (from n in BuildingRuleBean.m_lstAllLevels
			where !Geometry.LessThan(n.Elevation, 0.0) && !BuildingRuleBean.IfLevelIsMidLevel(n)
			select n into k
			orderby k.Elevation
			select k).ToList<Level>();
			for (int i = 1; i < list.Count; i++)
			{
				if (Geometry.LessThan(list[i].Elevation - list[i - 1].Elevation, BuildingRuleBean.twoPointTwoMeterLimit))
				{
					list.RemoveAt(i);
					i--;
				}
			}
			List<double> list2 = new List<double>();
			foreach (Level level in list)
			{
				list2.Add(level.Elevation);
			}
			if (list2.Count >= 3)
			{
				BuildingRuleBean.m_lstLevelKindEnum.Add(list2[2]);
			}
			if (list2.Count >= 4)
			{
				BuildingRuleBean.m_lstLevelKindEnum.Add(list2[3]);
			}
			BuildingRuleBean.m_lstLevelKindEnum.Add(double.MaxValue);
		}

		private static bool IfLevelIsMidLevel(Level input)
		{
			foreach (string pattern in Resources.Strs_KeyWordsOfMidLevel.Split(new char[]
			{
				','
			}))
			{
				if (Regex.IsMatch(input.Name, pattern))
				{
					return true;
				}
			}
			double num = double.MaxValue;
			foreach (Level level in BuildingRuleBean.m_lstAllLevels)
			{
				if (Geometry.LessThan(input.Elevation, level.Elevation, BuildingRuleBean.tolerance) && Geometry.LessThan(level.Elevation, num, BuildingRuleBean.tolerance))
				{
					num = level.Elevation;
				}
			}
			return Geometry.LessThan(num - input.Elevation, BuildingRuleBean.twoPointTwoMeterLimit);
		}

		private static List<Level> m_lstAllLevels = new List<Level>();

		private static List<double> m_lstLevelKindEnum = new List<double>();

		private List<double> m_lstAllMinEvacuationWidth = new List<double>();

		private FireLevelEnum m_useFireLevel;

		private RuleKindEnum m_useRuleKindEnum;

		private static double m_GroundElevation = 0.0;

		private static double tolerance = 0.01;

		private static double twoPointTwoMeterLimit = AssistFunc.mmToFeet(2200.0);
	}
}
